package command;

import gui.GUITile;
import card.Card;
import card.CreatureCard;

import command.CommandConstants.CommandType;

import core.Core;
import core.MapUtil;
import core.Tile;
import effect.Effect;
import effect.EffectUtil;

/**
 * 
 * @author Oscar
 *
 *Generates possible actions, commands, when a player selects a card.
 *Checks commands using CommandValidator, so that it always returns valid Commands.
 */

public class CommandGenerator {
	private static CommandGenerator me;
	
	public static CommandGenerator getInstance(){
		if(me == null)
			me = new CommandGenerator();
		return me;
	}

	/**
	 * returns the command for the given card targeting the given tile.
	 */
	public Command generateCommand(Card card, GUITile targetTile){
		
		Tile t = targetTile.getTile();
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		int cardID = Core.getInstance().getIdOfCard(card);
		int tileID = MapUtil.getIdOfTile(t);
			Command com = null;
		
			com = new Command(CommandType.playCard, cardID, 0, tileID, 0, 0, thisPlayerId);
				if(CommandValidator.getInstance().validateCommand(com)){
					return com;
				}
		
			com = new Command(CommandType.move, cardID, 0, tileID, 0, 0, thisPlayerId);
				if (CommandValidator.getInstance().validateCommand(com)){
					return com;
				}
			
			com = new Command(CommandType.attack, cardID, 0, tileID, 0, 0, thisPlayerId);
				if (CommandValidator.getInstance().validateCommand(com)){
					return com;
				}
			
				
			com = null;
			return com;
	}
	
	/**
	 * Generates a claimTile Command used by the given CreatureCard
	 * @return
	 */
	public Command generateClaimTileCommand(Card c){
		Command com = null;
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		if(c instanceof CreatureCard){
			int cardID=Core.getInstance().getIdOfCard(c);
			com = new Command(CommandType.claimTile, cardID, 0, 0, 0, 0, thisPlayerId);
			if (CommandValidator.getInstance().validateCommand(com)){
				return com;
			}
		}
		com = null;
		return com;
		
	}
	
	public Command generateBattleTargetCommand(Card attacker, Card defender){
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		int attackerId = Core.getInstance().getIdOfCard(attacker);
		int defenderId = Core.getInstance().getIdOfCard(defender);

		Command com = new Command(CommandType.battleTarget, attackerId, 0, 0, defenderId, 0, thisPlayerId);
		if(CommandValidator.getInstance().validateCommand(com))
			return com;
		
		com=null;
		return com;		
	}
	
	public Command generateBattleStartCommand(){
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		Command com = new Command(CommandType.battleStart, 0, 0, 0, 0, 0, thisPlayerId);
		
		return com;
		
	}
	
	/**
	 * Generates a command for no-target activatable Effects
	 * @param e
	 * @return
	 */
	public Command generateActivateEffectCommand(Effect e){
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		Card card = EffectUtil.getCard(e);
		int cardId = Core.getInstance().getIdOfCard(card);
		int effectId = card.getEffects().indexOf(e);
		
		Command com = new Command(CommandType.activateAbility, cardId, effectId, 0, 0, 0, thisPlayerId);	
		if(CommandValidator.getInstance().validateCommand(com))
			return com;
		
		com=null;
		return com;
	}
	
	/**
	 * Generates a command for tile targeted activatable Effects
	 * @param e
	 * @return
	 */
	public Command generateActivateEffectCommand(Effect e, GUITile targetTile){
		Tile tile = targetTile.getTile();
		int tileId = MapUtil.getIdOfTile(tile);
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		Card card = EffectUtil.getCard(e);
		int cardId = Core.getInstance().getIdOfCard(card);
		int effectId = card.getEffects().indexOf(e);
		
		Command com = new Command(CommandType.activateAbility, cardId, effectId, tileId, 0, 0, thisPlayerId);	
		if(CommandValidator.getInstance().validateCommand(com))
			return com;
		
		com=null;
		return com;
	}
	
	public Command generateEndTurnCommand(){
		int thisPlayerId=Core.getInstance().getIdOfThisPlayer();
		Command com =new Command(CommandType.endTurn, 0, 0, 0, 0, 0, thisPlayerId);
		if(CommandValidator.getInstance().validateCommand(com)){
			return com;
		}
		else return null;
	}
	
	
}
